package com.lvmama.rhino.web;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.lvmama.push.api.service.MipushStatsService;
import com.lvmama.rhino.base.BaseControllerSupport;
import com.lvmama.rhino.entity.MessageStatisticalVO;
import com.lvmama.rhino.entity.MessageVO;
import com.lvmama.rhino.entity.MiPushStats;
import com.lvmama.rhino.entity.StatsExportData;
import com.lvmama.rhino.enums.CommonStringType;
import com.lvmama.rhino.pojo.Message;
import com.lvmama.rhino.pojo.MessageStatistical;
import com.lvmama.rhino.service.MessageService;
import com.lvmama.rhino.utils.ExportExcelUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;


@Controller
@RequestMapping("message")
public class MessageController extends BaseControllerSupport {

    @Autowired
    private MessageService messageService;

    @Autowired
    private MipushStatsService mipushStatsService;

    /**
     * 推送消息信息列表
     *
     * @param model
     * @param messageVO
     * @return
     */
    @RequiresPermissions("sys:message:view")
    @RequestMapping("list")
    public String list(ModelMap model, MessageVO messageVO) {
        //获取当前时间
        String str = messageVO.getTimeDate();

        if (str == null) {
            //获取当前时间
            Date currentTime = new Date();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            String dateString = formatter.format(currentTime);
            messageVO.setTimeDate(dateString);
            //根据传入时间, 计算出查询条件的开始时间和结束时间
            DateTimeFormatter dateformatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
            Date start = DateTime.parse(dateString + " 00:00:00", dateformatter).toDate();
            Date end = DateTime.parse(dateString + " 23:59:59", dateformatter).toDate();
            //把时间转换成字符串
            SimpleDateFormat formatterStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            messageVO.setStartDate(formatterStr.format(start));
            messageVO.setEndDate(formatterStr.format(end));
        } else {
            String dateString = messageVO.getTimeDate();
            DateTimeFormatter dateformatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
            Date start = DateTime.parse(dateString + " 00:00:00", dateformatter).toDate();
            Date end = DateTime.parse(dateString + " 23:59:59", dateformatter).toDate();
            SimpleDateFormat formatterStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            messageVO.setStartDate(formatterStr.format(start));
            messageVO.setEndDate(formatterStr.format(end));
        }

        CommonStringType[] getPlatformType = CommonStringType.getPlatformType();
        CommonStringType[] getPushChannelType = CommonStringType.getPushChannelType();
        CommonStringType[] getPushCategoryType = CommonStringType.getPushCategoryType();
        CommonStringType[] getPushTypeType = CommonStringType.getPushTypeType();
        //设备平台下拉列表
        List<CommonStringType> platformTypeList = Arrays.asList(getPlatformType);
        //推送渠道下拉列表
        List<CommonStringType> pushChannelTypeList = Arrays.asList(getPushChannelType);
        //推送类别下拉列表
        List<CommonStringType> pushCategoryTypeList = Arrays.asList(getPushCategoryType);
        //推送类型下拉列表
        List<CommonStringType> pushTypeTypeList = Arrays.asList(getPushTypeType);

        PageInfo<Message> page = messageService.getMessageListPage(messageVO);
        List<Message> list = page.getList();

        //通过迭代将推送类别英文内容替换为对应的汉字内容
        for (Message message : list) {
            String pushCategory = message.getPushCategory();
            String pushChannel = message.getPushChannel();
            String pushType = message.getPushType();
            if (pushType.equals(CommonStringType.PROVINCE.getValue())) {
                message.setMessageId("省份推送");
            }
            for (CommonStringType obj : pushChannelTypeList) {
                if (pushChannel != null && !pushChannel.equals("") && pushChannel.equals(obj.getValue())) {
                    String[] showName = obj.getShowName().split("\\(");
                    message.setPushChannel(showName[0]);
                }
            }
            for (CommonStringType obj : pushCategoryTypeList) {
                if (pushCategory != null && !pushCategory.equals("") && pushCategory.equals(obj.getValue())) {
                    String[] showName = obj.getShowName().split("\\(");
                    message.setPushCategory(showName[0]);
                }
            }
        }

        logger.info("推送消息信息列表page.getList()=" + page.getList());
        model.addAttribute("page", page);
        model.addAttribute("messages", list);
        model.addAttribute("conditionMessageVO", messageVO);
        model.addAttribute("platformTypeList", platformTypeList);
        model.addAttribute("pushChannelTypeList", pushChannelTypeList);
        model.addAttribute("pushCategoryTypeList", pushCategoryTypeList);
        model.addAttribute("pushTypeTypeList", pushTypeTypeList);
        model.addAttribute("tab", "tabManage");
        return "application/pushStatistic/messageList";
    }


    /**
     * 推送消息统计列表
     *
     * @param model
     * @param messageStatisticalVO
     * @return
     */
    @RequiresPermissions("sys:message:view")
    @RequestMapping("statistical")
    public String statisticalList(ModelMap model, MessageStatisticalVO messageStatisticalVO) {
        //将日期控件中的时间解析为开始时间和结束时间
        String[] split = messageStatisticalVO.getChooseTimeVO().split("-");
        DateTimeFormatter formater = DateTimeFormat.forPattern("MM/dd/yyyy HH:mm:ss");
        Date startDate = DateTime.parse(split[0].trim() + " 00:00:00", formater).toDate();
        Date endDate = DateTime.parse(split[1].trim() + " 23:59:59", formater).toDate();
        messageStatisticalVO.setStartDate(startDate);
        messageStatisticalVO.setEndDate(endDate);

        CommonStringType[] getPlatformType = CommonStringType.getPlatformType();
        CommonStringType[] getPushChannelType = CommonStringType.getPushChannelType();
        CommonStringType[] getPushCategoryType = CommonStringType.getPushCategoryType();
        CommonStringType[] getPushTypeType = CommonStringType.getPushTypeType();
        //设备品台下拉列表
        List<CommonStringType> platformTypeList = Arrays.asList(getPlatformType);
        //推送渠道下拉列表
        List<CommonStringType> pushChannelTypeList = Arrays.asList(getPushChannelType);
        //推送类别下拉列表
        List<CommonStringType> pushCategoryTypeList = Arrays.asList(getPushCategoryType);
        //推送类型下拉列表
        List<CommonStringType> pushTypeTypeList = Arrays.asList(getPushTypeType);

        PageInfo<MessageStatistical> page = messageService.getMessageStatisticalList(messageStatisticalVO);

        List<MessageStatistical> list = page.getList();

        //当数据统计入库出现不可控因素丢失送达量数据时，对数据采取处理
        for (MessageStatistical messageStatistical : list) {
            Integer pushDeliverCounts = messageStatistical.getPushDeliverCounts();
            Integer pushClickCounts = messageStatistical.getPushClickCounts();
            //仅对安卓处理，ios无送达量
            String platform = messageStatistical.getPlatform();
            if (pushDeliverCounts != null && pushClickCounts != null && pushDeliverCounts < pushClickCounts && "ANDROID".equals(platform)) {
                Integer newPushClickCounts = pushDeliverCounts;
                messageStatistical.setPushClickCounts(newPushClickCounts);
                messageStatistical.setClickDeliverRate("100%");
            }
        }

        model.addAttribute("pageStatistical", page);
        model.addAttribute("messageStatisticalList", list);
        model.addAttribute("conditionMessageStatisticalVO", messageStatisticalVO);
        model.addAttribute("platformTypeList", platformTypeList);
        model.addAttribute("pushChannelTypeList", pushChannelTypeList);
        model.addAttribute("pushCategoryTypeList", pushCategoryTypeList);
        model.addAttribute("pushTypeTypeList", pushTypeTypeList);
        model.addAttribute("tab", "tabStatistical");
        return "application/pushStatistic/messageList";
    }


    /**
     * 跳转历史消息统计页面
     *
     * @param model
     * @return
     */
    @RequiresPermissions("sys:historyMsg:view")
    @RequestMapping("history")
    public String history(ModelMap model) {
        return "application/pushStatistic/historyMsg";
    }

    /**
     * 通过ajax从后台获取消息回执数量信息
     *
     * @return
     */
    @RequestMapping("ajaxData")
    @ResponseBody
    public Map<String, Object> ajaxData() {
        //获取前15天日期
        Date date = new Date();//取时间
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, -15);
        date = calendar.getTime();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String[] dateString = new String[15];
        for (int i = 0; i < 15; i++) {
            calendar.setTime(date);
            calendar.add(Calendar.DATE, 1);
            date = calendar.getTime();
            dateString[i] = formatter.format(date);
        }

        //查询前15天中各类别下的消息回执的数量
        List<Message> messageList = messageService.selectDateCategoryCount(0, 14);
        int[] normalData = new int[15];
        int[] payOrderData = new int[15];
        int[] accurateOrderData = new int[15];
        int[] accurateDetailData = new int[15];
        int[] couponData = new int[15];
        int[] ticketTravelData = new int[15];
        int[] ticketCommentData = new int[15];
        int[] changedData = new int[15];
        int[] associtaionData = new int[15];
        int[] personaliseData = new int[15];
        int[] travelAsstData = new int[15];
        //将sql查询的结果解析成相对应的数组
        for (int i = 0; i < dateString.length; i++) {
            for (Message message : messageList) {
                String pushCategory = message.getPushCategory();//推送类别
                Date beginDate = message.getBeginDate();//推送日期
                if (pushCategory != null && beginDate != null) {
                    String beginDateStr = formatter.format(beginDate);
                    int count = message.getCount();//消息数量
                    if (pushCategory.equals(CommonStringType.NORMAL.getValue())) {
                        if (dateString[i].equals(beginDateStr)) {
                            normalData[i] = count;
                        }
                    } else if (pushCategory.equals(CommonStringType.PAY_ORDER.getValue())) {
                        if (dateString[i].equals(beginDateStr)) {
                            payOrderData[i] = count;
                        }
                    } else if (pushCategory.equals(CommonStringType.ACCURATE_ORDER.getValue())) {
                        if (dateString[i].equals(beginDateStr)) {
                            accurateOrderData[i] = count;
                        }
                    } else if (pushCategory.equals(CommonStringType.ACCURATE_DETAIL.getValue())) {
                        if (dateString[i].equals(beginDateStr)) {
                            accurateDetailData[i] = count;
                        }
                    } else if (pushCategory.equals(CommonStringType.COUPON.getValue())) {
                        if (dateString[i].equals(beginDateStr)) {
                            couponData[i] = count;
                        }
                    } else if (pushCategory.equals(CommonStringType.TICKET_TRAVEL.getValue())) {
                        if (dateString[i].equals(beginDateStr)) {
                            ticketTravelData[i] = count;
                        }
                    } else if (pushCategory.equals(CommonStringType.TICKET_COMMENT.getValue())) {
                        if (dateString[i].equals(beginDateStr)) {
                            ticketCommentData[i] = count;
                        }
                    } else if (pushCategory.equals(CommonStringType.CHANGED.getValue())) {
                        if (dateString[i].equals(beginDateStr)) {
                            changedData[i] = count;
                        }
                    } else if (pushCategory.equals(CommonStringType.ASSOCITAION.getValue())) {
                        if (dateString[i].equals(beginDateStr)) {
                            associtaionData[i] = count;
                        }
                    } else if (pushCategory.equals(CommonStringType.PERSONALISE.getValue())) {
                        if (dateString[i].equals(beginDateStr)) {
                            personaliseData[i] = count;
                        }
                    } else if (pushCategory.equals(CommonStringType.TRAVEL_ASST.getValue())) {
                        if (dateString[i].equals(beginDateStr)) {
                            travelAsstData[i] = count;
                        }
                    }
                }
            }
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("xAxisData", dateString);
        map.put("normalData", normalData);
        map.put("payOrderData", payOrderData);
        map.put("accurateOrderData", accurateOrderData);
        map.put("accurateDetailData", accurateDetailData);
        map.put("couponData", couponData);
        map.put("ticketTravelData", ticketTravelData);
        map.put("ticketCommentData", ticketCommentData);
        map.put("changedData", changedData);
        map.put("associtaionData", associtaionData);
        map.put("personaliseData", personaliseData);
        map.put("travelAsstData", travelAsstData);
        return map;
    }


    /**
     * 导出推送消息统计
     *
     * @param messageStatisticalVO
     * @param response
     * @param request
     * @throws IOException
     */
    @RequestMapping("exportStatistical")
    public void exportData(MessageStatisticalVO messageStatisticalVO, HttpServletResponse response, HttpServletRequest request) throws IOException {
        //将日期控件中的时间解析为开始时间和结束时间
        String[] split = messageStatisticalVO.getChooseTimeVO().split("-");
        DateTimeFormatter formater = DateTimeFormat.forPattern("MM/dd/yyyy HH:mm:ss");
        Date startDate = DateTime.parse(split[0].trim() + " 00:00:00", formater).toDate();
        Date endDate = DateTime.parse(split[1].trim() + " 23:59:59", formater).toDate();
        /*boolean flag = CompareTwoDateOutOf30(startDate, endDate);*/
        int startDay = getDaysOfDate(startDate);
        int endDay = getDaysOfDate(endDate);
        Date miStartDate = null;
        if (endDay - startDay > 30) {
            Calendar c = Calendar.getInstance();
            c.setTime(endDate);
            c.add(Calendar.DAY_OF_YEAR, -29);
            miStartDate = c.getTime();
        } else {
            miStartDate = startDate;
        }
        messageStatisticalVO.setStartDate(startDate);
        messageStatisticalVO.setEndDate(endDate);

        //推送类别下拉列表
        CommonStringType[] getPushCategoryType = CommonStringType.getPushCategoryType();
        List<CommonStringType> pushCategoryTypeList = Arrays.asList(getPushCategoryType);

        //查询导出推送消息统计
        List<MessageStatistical> list = messageService.exportStatistical(messageStatisticalVO);

        //通过迭代将推送类别英文内容替换为对应的汉字内容
        for (MessageStatistical message : list) {
            String pushCategory = message.getPushCategory();
            for (CommonStringType obj : pushCategoryTypeList) {
                if (pushCategory != null && !pushCategory.equals("") && pushCategory.equals(obj.getValue())) {
                    String[] showName = obj.getShowName().split("\\(");
                    message.setPushCategory(showName[0]);
                }
            }
        }

        //导出excel文件
        ExportExcelUtils ex = new ExportExcelUtils();
        String pushCategory = messageStatisticalVO.getPushCategoryStatisticalVO();
        String[] headers;
        if (pushCategory.equals(CommonStringType.NORMAL.getValue()) || pushCategory.equals(CommonStringType.MEMBER_MODEL.getValue()) || pushCategory.equals(CommonStringType.PERSONALISE.getValue())) {
            headers = new String[]{"推送日期", "设备平台", "推送类别", "推送标题", "推送内容", "推送总量", "推送送达量", "推送点击量", "送达量/推送总量", "点击量/送达量"};
        } else {
            //excel文件的每列字段名称
            headers = new String[]{"推送日期", "设备平台", "推送类别", "推送总量", "推送送达量", "推送点击量", "送达量/推送总量", "点击量/送达量"};
        }

        String codedFileName = null;
        OutputStream fOut = null;
        try {
            // 生成提示信息，
            response.setContentType("application/vnd.ms-excel");
            // 进行转码，使其支持中文文件名
            codedFileName = java.net.URLEncoder.encode("推送消息统计", "UTF-8");
            response.setHeader("content-disposition", "attachment;filename=" + codedFileName + ".xls");
            fOut = response.getOutputStream();
            Field[] fields = getFields(headers);
            /*ex.exportExcel("推送消息统计文档", headers, fields, list, fOut, "yyyy-MM-dd");*/
            if (pushCategory.equals(CommonStringType.NORMAL.getValue()) || pushCategory.equals(CommonStringType.MEMBER_MODEL.getValue()) || pushCategory.equals(CommonStringType.PERSONALISE.getValue())) {
                ex.getHSSFSheet("推送消息统计文档", headers, fields, list, "yyyy-MM-dd HH:mm:ss");
            } else {
                ex.getHSSFSheet("推送消息统计文档", headers, fields, list, "yyyy-MM-dd");
            }

            //查询小米统计的安卓推送数据
            String mipushStats = mipushStatsService.getMipushStats("ANDROID", miStartDate, endDate);
            if (StringUtils.isBlank(mipushStats) || mipushStats.contains("error")) {
                logger.info("查询安卓推送数据调用接口发生异常");
                ex.writeToOutput(fOut);
                return;
            }
            MiPushStats androidStats = JSON.parseObject(mipushStats, MiPushStats.class);
            List<StatsExportData> data1 = androidStats.getData().getData();
            for (StatsExportData statsExportData : data1) {
                statsExportData.setPlatform("ANDROID");
            }
            String mipushStats2 = mipushStatsService.getMipushStats("IPHONE", miStartDate, endDate);
            if (StringUtils.isBlank(mipushStats2) || mipushStats2.contains("error")) {
                logger.info("查询iphone推送数据调用接口发生异常");
                ex.writeToOutput(fOut);
                return;
            }
            MiPushStats iphoneStats = JSON.parseObject(mipushStats2, MiPushStats.class);
            List<StatsExportData> list2 = iphoneStats.getData().getData();
            for (StatsExportData statsExportData : list2) {
                statsExportData.setPlatform("IPHONE");
            }
            data1.addAll(list2);
            String[] headers1 = new String[]{"推送日期", "设备平台", "单推推送量", "别名推送量", "按用户名推送量", "注册id推送量",
                    "topic推送量", "到达量", "点击量"};
            Field[] fields1 = getStatFields(headers1);
            ex.getHSSFSheet("参考数据", headers1, fields1, data1, "yyyy-MM-dd");
            ex.writeToOutput(fOut);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 根据每列字段名称创建需要导出字段的数组
     *
     * @param headers
     * @return
     */
    public Field[] getFields(String[] headers) {
        Field[] fields = new Field[headers.length];
        MessageStatistical t = new MessageStatistical();
        try {
            for (int i = 0; i < headers.length; i++) {
                if (headers[i].equals("推送日期")) {
                    fields[i] = t.getClass().getDeclaredField("pushDate");
                } else if (headers[i].equals("设备平台")) {
                    fields[i] = t.getClass().getDeclaredField("platform");
                } else if (headers[i].equals("推送类别")) {
                    fields[i] = t.getClass().getDeclaredField("pushCategory");
                } else if (headers[i].equals("推送标题")) {
                    fields[i] = t.getClass().getDeclaredField("title");
                } else if (headers[i].equals("推送内容")) {
                    fields[i] = t.getClass().getDeclaredField("content");
                } else if (headers[i].equals("推送总量")) {
                    fields[i] = t.getClass().getDeclaredField("pushTotalCounts");
                } else if (headers[i].equals("推送送达量")) {
                    fields[i] = t.getClass().getDeclaredField("pushDeliverCounts");
                } else if (headers[i].equals("推送点击量")) {
                    fields[i] = t.getClass().getDeclaredField("pushClickCounts");
                } else if (headers[i].equals("送达量/推送总量")) {
                    fields[i] = t.getClass().getDeclaredField("deliverTotalRate");
                } else if (headers[i].equals("点击量/送达量")) {
                    fields[i] = t.getClass().getDeclaredField("clickDeliverRate");
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return fields;
    }

    public Field[] getStatFields(String[] headers) {
        Field[] fields = new Field[headers.length];
        StatsExportData statsExportData = new StatsExportData();
        try {
            for (int i = 0; i < headers.length; i++) {
                if (headers[i].equals("推送日期")) {
                    fields[i] = statsExportData.getClass().getDeclaredField("date");
                }
                if (headers[i].equals("设备平台")) {
                    fields[i] = statsExportData.getClass().getDeclaredField("platform");
                }
                if (headers[i].equals("单推推送量")) {
                    fields[i] = statsExportData.getClass().getDeclaredField("single_recipients");
                }
                if (headers[i].equals("别名推送量")) {
                    fields[i] = statsExportData.getClass().getDeclaredField("alias_recipients");
                }
                if (headers[i].equals("按用户名推送量")) {
                    fields[i] = statsExportData.getClass().getDeclaredField("useraccount_recipients");
                }
                if (headers[i].equals("注册id推送量")) {
                    fields[i] = statsExportData.getClass().getDeclaredField("regid_recipients");
                }
                if (headers[i].equals("topic推送量")) {
                    fields[i] = statsExportData.getClass().getDeclaredField("broadcast_recipients");
                }
                if (headers[i].equals("到达量")) {
                    fields[i] = statsExportData.getClass().getDeclaredField("received");
                }
                if (headers[i].equals("点击量")) {
                    fields[i] = statsExportData.getClass().getDeclaredField("click");
                }
            }
            return fields;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
    
   /* private boolean CompareTwoDateOutOf30(Date date1,Date date2){
        Calendar c1=Calendar.getInstance();
    	c1.setTime(date1);
    	int day1=c1.get(Calendar.DAY_OF_YEAR);
    	c1.setTime(date2);
    	int day2=c1.get(Calendar.DAY_OF_YEAR);
    	return day2-day1>30?true:false;
    }*/

    private int getDaysOfDate(Date date) {
        Calendar c1 = Calendar.getInstance();
        c1.setTime(date);
        return c1.get(Calendar.DAY_OF_YEAR);
    }

}
